//
//  UAPI.swift
//  U17
//
//  Created by charles on 2017/9/29.
//  Copyright © 2017年 None. All rights reserved.
//

import UIKit
import Moya
import HandyJSON
import SVProgressHUD
let LoadingPlugin = NetworkActivityPlugin { (type, target) in
    guard let vc = topVC else { return }
    switch type {
    case .began:
        SVProgressHUD.setBackgroundColor(UIColor.tip)
        SVProgressHUD.setDefaultMaskType(.black)
        SVProgressHUD.show()
        break
    case .ended:
        
        break
    }
}
let timeoutClosure = {(endpoint: Endpoint, closure: MoyaProvider<UModel>.RequestResultClosure) -> Void in
    
    if var urlRequest = try? endpoint.urlRequest() {
        urlRequest.timeoutInterval = 120
        closure(.success(urlRequest))
    } else {
        closure(.failure(MoyaError.requestMapping(endpoint.url)))
    }
}

let ApiProvider = MoyaProvider<UModel>(requestClosure: timeoutClosure)
let ApiLoadingProvider = MoyaProvider<UModel>(requestClosure: timeoutClosure, plugins: [LoadingPlugin])

//class UModel : TargetType {
//    var baseURL: URL {
//        return URL(string: "https://api.ldnkj.com/tire-server")!
//    }
//
//    var path: String {
//        return getPath()
//    }
//
//    var method: Moya.Method {
//        return .post
//    }
//
//    var sampleData: Data {
//        return Data()
//    }
//
//    var task: Task {
//        if let params = self.getParams() {
//            return .requestData(jsonToData(jsonDic: params)!)
//        }
//        return .requestPlain
//    }
//
//    var headers: [String : String]?
//
//    func getPath() -> String {
//        return "/"
//    }
//
//    func getParams() -> [String : Any]? {
//        return nil
//    }
//
//    private func jsonToData(jsonDic:Dictionary<String, Any>) -> Data? {
//        if (!JSONSerialization.isValidJSONObject(jsonDic)) {
//            print("is not a valid json object")
//            return nil
//        }
//        let data = try? JSONSerialization.data(withJSONObject: jsonDic, options: [])
//        _ = String(data:data!, encoding: String.Encoding.utf8)
//        return data
//    }
//}
//
//struct TestLoginType {
//    static let login = 0
//    static let register = 1
//}
//
//class TestLogin: UModel {
//    var params : [String : Any]?
//    var type = TestLoginType.register
//    var selfMethod : Moya.Method = .get
//
//    convenience init(type: Int, params: [String: Any]) {
//        self.init(method: .get, type: type, params: params)
//    }
//
//    init(method: Moya.Method, type: Int, params: [String: Any]) {
//        self.params = params
//        self.type = type
//        self.selfMethod = method
//    }
//
//    override func getPath() -> String {
//        return "/app/installer/login"
//    }
//
//    override func getParams() -> [String : Any]? {
//        switch self.type {
//        case TestLoginType.login:
//            return self.params;
//        default:
//            return nil;
//        }
//    }
//}

enum UApi {
    
    case login(params: [String: Any])//登录
    case sendCode(params: [String: Any])//登录
    case msgList(params: [String: Any])
    case homeSwiper(params: [String: Any])                           // 首页轮播              //新闻按type
    case register(params: [String: Any])
    case getState(params: [String: Any])
    case uploadImage(fiileUrl: URL)
   
}

extension UApi: TargetType {
    var baseURL: URL { return URL(string: "https://api.ldnkj.com/tire-server")! }
    
    var path: String {
        switch self {
        case .sendCode: return "/app/sendSms"
        case .login: return "/app/installer/login"
        case .register: return "/app/installer/register"
        case .homeSwiper: return "/app/installer/serviceAdvertiseList"
        case .msgList: return "/app/installer/getMessageList"
        case .getState: return "/app/installer/getStatus"
        case .uploadImage: return "/app/uploadFile"
        }
    }
    
    var method: Moya.Method {
        switch self {
        case .login,.msgList,.sendCode,.register,.uploadImage:
            return .post
        case
        .homeSwiper,.getState:
            return .get
        }
    }
    var task: Task {
        //字典转json
        func jsonToData(jsonDic:Dictionary<String, Any>) -> Data? {
            if (!JSONSerialization.isValidJSONObject(jsonDic)) {
                print("is not a valid json object")
                return nil
            }
            let data = try? JSONSerialization.data(withJSONObject: jsonDic, options: [])
            _ = String(data:data!, encoding: String.Encoding.utf8)
            return data
        }
        switch self {
        case let .login(params):
            return .requestData(jsonToData(jsonDic: params)!)
        case let .homeSwiper(params):
            return .requestParameters(parameters: params, encoding: URLEncoding.default)
        case let .sendCode(params):
            return .requestData(jsonToData(jsonDic: params)!)
        case let .register(params):
            return .requestData(jsonToData(jsonDic: params)!)
        case let .msgList(params):
            return .requestData(jsonToData(jsonDic: params)!)
        case let .getState(params):
            return .requestParameters(parameters: params, encoding: URLEncoding.default)
        case let .uploadImage(fiileUrl):
            let formData = MultipartFormData(provider: .file(fiileUrl), name: "file", fileName: "file.png", mimeType: "image/png")
            return .uploadMultipart([formData])
        
            //            return .uploadCompositeMultipart([formData], urlParameters: ["file" : formData])
            
        }
        //        return .requestParameters(parameters: parmeters, encoding: URLEncoding.default)
    }
    
    var sampleData: Data { return "".data(using: String.Encoding.utf8)! }
    var headers: [String : String]? {
        var header: [String:String] = [:]
        if let token = UserDefaults.standard.string(forKey: String.token) {
            header["token"] = token
        }
        header["Content-Type"] = "application/json;charset=UTF-8"
        return header
    }
}


extension Response {
    func mapModel<T: HandyJSON>(_ type: T.Type) throws -> T {
        let jsonString = String(data: data, encoding: .utf8)
        guard let model = JSONDeserializer<T>.deserializeFrom(json: jsonString) else {
            throw MoyaError.jsonMapping(self)
        }
        return model
    }
}

extension MoyaProvider {
    @discardableResult
    //请求数据
    open func request<T: HandyJSON>(_ target: Target,
                                    model: T.Type,
                                    completion: ((_ msg: String?, _ returnData: T?) -> Void)?) -> Cancellable? {
        
        return request(target, completion: { (result) in
            guard let completion = completion else { return }
            guard let returnData = try? result.value?.mapModel(ResponseData<T>.self) else {
                completion(nil, nil)
                return
            }
            let code = returnData?.code
            guard let vc = topVC else { return }
            SVProgressHUD.dismiss()
            switch code {
            case 200:
                completion(returnData?.msg, returnData?.data)
            case 401,902:
                UserDefaults.standard.set("", forKey: String.token)
                
                vc.navigationController?.present(UNavigationController(rootViewController: LoginViewController()), animated: false, completion: nil)
                guard let msg = returnData?.msg else { return }
                Toast.toastError(msg)
            case 500:
                print(returnData!)
                //            case 901:
            //                Toast.toastError("参数异常")
            default :
                if let msg = returnData?.msg {
                    Toast.toastError(msg)
                }
                
                break
            }
        })
    }
}


